

#include "TDAListaOrdenada.h"
#include <stdio.h>
#include <malloc.h>
#include <memory.h>


void lo_Crear (TListaOrdenada *pLo, int TamanioDato)
{
    pLo->Corriente = NULL;
    pLo->Primero = NULL;
    pLo->TamanioDato = TamanioDato;
}

void lo_Vaciar (TListaOrdenada *pLo)
{
    TNodoSimple *pNodo, *Siguiente;
    for (pNodo = pLo->Primero;(pNodo);pNodo = Siguiente)
    {
        Siguiente = pNodo->Siguiente;
        free(pNodo->Elem);
        free(pNodo);
    }
    pLo->Primero = pLo->Corriente = NULL;
}

int lo_Vacia(TListaOrdenada Lo)
{
    return (Lo.Primero == NULL);
}

void lo_ObtenerCorriente(TListaOrdenada Lo, void *pE)
{
    memcpy (pE,Lo.Corriente->Elem,Lo.TamanioDato);

}

void lo_ModifCorriente(TListaOrdenada *pLo, void *pE)
{
    memcpy(pLo->Corriente->Elem,pE,pLo->TamanioDato);
}


int lo_MoverCorriente(TListaOrdenada *pLo, TMovimiento_Lo M)
{
    switch (M)
    {
        case LO_PRIMERO:    pLo->Corriente = pLo->Primero;
                            break;
        case LO_SIGUIENTE:  if (pLo->Corriente->Siguiente == NULL)
                            return FALSE;
                            else
                            pLo->Corriente = pLo->Corriente->Siguiente;
                            break;
        case LO_ANTERIOR:   return FALSE;
    }
    return TRUE;
}


void lo_EliminarCorriente(TListaOrdenada *pLo)
{
    TNodoSimple *PNodo = pLo->Corriente;

    if (pLo->Corriente == pLo->Primero)
    {
        pLo->Primero = pLo->Corriente->Siguiente;
        pLo->Corriente = pLo->Primero;
    }
    else
    {
        TNodoSimple *TNAux = pLo->Primero;
        while (TNAux->Siguiente != pLo->Corriente)
        {
            TNAux = TNAux->Siguiente;
        }
        TNAux->Siguiente = pLo->Corriente->Siguiente;
        if (TNAux->Siguiente)
        {
            pLo->Corriente = TNAux->Siguiente;
        }
        pLo->Corriente = TNAux;
    }
    free(PNodo->Elem);
    free(PNodo);
}


int lo_Insertar(TListaOrdenada *pLo, TMovimiento_Lo M, void *pE)
{
    TNodoSimple *pNodo = (TNodoSimple*) malloc(sizeof (TNodoSimple));
    if (!pNodo)
    {
        return FALSE;
    }
    if ((pLo->Primero == NULL) || (M == LO_PRIMERO) || ((M == LO_ANTERIOR) && (pLo->Primero == pLo->Corriente)))
    {
        pNodo->Siguiente = pLo->Primero;
        pLo->Primero = pLo->Corriente = pNodo;
    }
    else
    {
        if(M == LO_SIGUIENTE)
        {
            pNodo->Siguiente = pLo->Corriente->Siguiente;
            pLo->Corriente->Siguiente = pNodo;
        }
        else
        {
            TNodoSimple *PAux = pLo->Primero;
            while (PAux->Siguiente != pLo->Corriente)
            {
                PAux = PAux->Siguiente;
                PAux->Siguiente = pNodo;
                pNodo->Siguiente = pLo->Corriente;
            }
        }
    }
    pNodo->Elem = malloc(sizeof pLo->TamanioDato);
    memcpy(pNodo->Elem,pE,pLo->TamanioDato);
    pLo->Corriente = pNodo;
    return TRUE;
}

int lo_InsertarOrdenado(TListaOrdenada *pLo,void *Elem)
{
    if (lo_Vacia(*pLo))
    {
        lo_Insertar(pLo, LO_PRIMERO,Elem);
    }
    else
    {
        void *E1;
        int E;
        lo_ObtenerCorriente(*pLo,E1);
        if (E1 > Elem)
        {
            E = lo_MoverCorriente(pLo,LO_PRIMERO);
            lo_ObtenerCorriente(*pLo,&E1);
        }
        while ((E1 < Elem) && (!E))
        {
                E = lo_MoverCorriente (pLo,LO_SIGUIENTE);
                lo_ObtenerCorriente(*pLo,&E1);
                if (!E)
                {
                    lo_Insertar(pLo,LO_ANTERIOR,&Elem);
                }
                else
                {
                    lo_Insertar(pLo,LO_SIGUIENTE,&Elem);
                }
            }
        }
    return TRUE;
}


